//
//  XPProgressView.m
//  ProgressDemo
//
//  Created by nhope on 2017/2/9.
//  Copyright © 2017年 xiaopin. All rights reserved.
//

#import "XPProgressView.h"
#import "XPScoreLevelItem.h"

@interface XPProgressView ()

/// 背景图层
@property (nonatomic, strong) CAShapeLayer *backgroundLayer;
/// 渐变色图层
@property (nonatomic, strong) CAGradientLayer *gradientLayer;
/// 进度条图层
@property (nonatomic, strong) CAShapeLayer *progressLayer;
/// 分割线
@property (nonatomic, strong) UIView *separatorLine;

@end


@implementation XPProgressView

@synthesize scoreLabel = _scoreLabel;
@synthesize scoreLevelLabel = _scoreLevelLabel;

#pragma mark - Lifecycle

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self configureUserInterface];
    }
    return self;
}

- (void)awakeFromNib {
    [super awakeFromNib];
    [self configureUserInterface];
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    CGFloat maxWidth = CGRectGetWidth(self.frame);
    CGFloat maxHeight = CGRectGetHeight(self.frame);
    
    CGFloat separatorMargin = 3.0;
    CGFloat scoreHeight = [_scoreLabel.text boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:_scoreLabel.font} context:NULL].size.height;
    _scoreLabel.frame = CGRectMake(0.0, maxHeight*0.5-scoreHeight+10.0, maxWidth, scoreHeight);
    _separatorLine.frame = CGRectMake((maxWidth-_separatorLineWidth)/2, CGRectGetMaxY(_scoreLabel.frame)+separatorMargin, _separatorLineWidth, 1.0);
    _scoreLevelLabel.frame = CGRectMake(0.0, CGRectGetMaxY(_separatorLine.frame)+separatorMargin, maxWidth, 15.0);
    
    CGRect rect = CGRectMake(_progressLineWidth/2,
                             _progressLineWidth/2,
                             maxWidth-_progressLineWidth,
                             maxHeight-_progressLineWidth);
    _gradientLayer.frame = self.bounds;
    _backgroundLayer.frame = rect;
    _progressLayer.frame = rect;
    
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetWidth(rect)/2, CGRectGetHeight(rect)/2) radius:CGRectGetWidth(rect)/2 startAngle:M_PI_2+M_PI_4 endAngle:M_PI*2+M_PI_4 clockwise:YES];
    _backgroundLayer.path = path.CGPath;
    _progressLayer.path = path.CGPath;
    
    _progressLayer.strokeEnd = 0.0;
    [self startProgressAnimation];
}

#pragma mark - Private

- (void)configureUserInterface {
    _progressLineWidth = 10.0;
    _score = 5.0;
    _separatorLineWidth = 50.0;
    [self.layer addSublayer:self.backgroundLayer];
    [self.layer addSublayer:self.gradientLayer];
    [self addSubview:self.scoreLabel];
    [self addSubview:self.separatorLine];
    [self addSubview:self.scoreLevelLabel];
}

- (void)startProgressAnimation {
    float progress = _score<=0 ? 0.0 : _currentScore/_score;
    [CATransaction begin];
    [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
    [CATransaction setAnimationDuration:1.0];
    _progressLayer.strokeEnd = progress;
    [CATransaction commit];
}

#pragma mark - setter & getter

- (CAShapeLayer *)backgroundLayer {
    if (nil == _backgroundLayer) {
        _backgroundLayer = [CAShapeLayer layer];
        _backgroundLayer.lineCap = kCALineCapRound;
        _backgroundLayer.fillColor = [[UIColor clearColor] CGColor];
        _backgroundLayer.strokeColor = [UIColor colorWithRed:183/255.0 green:183/255.0 blue:183/255.0 alpha:1.0].CGColor;
        _backgroundLayer.lineWidth = _progressLineWidth;
    }
    return _backgroundLayer;
}

- (CAShapeLayer *)progressLayer {
    if (nil == _progressLayer) {
        _progressLayer = [CAShapeLayer layer];
        _progressLayer.lineCap = kCALineCapRound;
        _progressLayer.fillColor = [[UIColor clearColor] CGColor];
        _progressLayer.strokeColor = [UIColor whiteColor].CGColor;
        _progressLayer.lineWidth = _progressLineWidth;
        _progressLayer.strokeEnd = 0.0;
    }
    return _progressLayer;
}

- (CALayer *)gradientLayer {
    if (nil == _gradientLayer) {
        _gradientLayer =  [CAGradientLayer layer];
        _gradientLayer.startPoint = CGPointMake(0.0, 0.5);
        _gradientLayer.endPoint = CGPointMake(1.0, 0.5);
        _gradientLayer.mask = self.progressLayer;
        _gradientLayer.colors = _gradientColors;
    }
    return _gradientLayer;
}

- (UILabel *)scoreLabel {
    if (nil == _scoreLabel) {
        _scoreLabel = [[UILabel alloc] init];
        _scoreLabel.font = [UIFont systemFontOfSize:30.0];
        _scoreLabel.text = @"0.0分";
        _scoreLabel.textAlignment = NSTextAlignmentCenter;
    }
    return _scoreLabel;
}

- (UILabel *)scoreLevelLabel {
    if (nil == _scoreLevelLabel) {
        _scoreLevelLabel = [[UILabel alloc] init];
        _scoreLevelLabel.font = [UIFont systemFontOfSize:14.0];
        _scoreLevelLabel.textAlignment = NSTextAlignmentCenter;
    }
    return _scoreLevelLabel;
}

- (UIView *)separatorLine {
    if (nil == _separatorLine) {
        _separatorLine = [[UIView alloc] init];
        _separatorLine.backgroundColor = [UIColor colorWithRed:185/255.0 green:185/255.0 blue:185/255.0 alpha:1.0];
    }
    return _separatorLine;
}

- (void)setProgressLineWidth:(CGFloat)progressLineWidth {
    _progressLineWidth = progressLineWidth;
    _backgroundLayer.lineWidth = progressLineWidth;
    _progressLayer.lineWidth = progressLineWidth;
}

- (void)setGradientColors:(NSArray *)gradientColors {
    _gradientColors = [gradientColors copy];
    _gradientLayer.colors = gradientColors;
}

- (void)setScore:(float)score {
    _score = MAX(0.0, score);
    [self startProgressAnimation];
}

- (void)setCurrentScore:(float)currentScore {
    _currentScore = MAX(0.0, MIN(currentScore, _score));
    _scoreLabel.text = [NSString stringWithFormat:@"%.1f分", _currentScore];
    for (XPScoreLevelItem *item in _levelItems) {
        if ((item.minValue==0 && _currentScore==item.minValue) ||
            (_currentScore>item.minValue && _currentScore<=item.maxValue)) {
            _scoreLevelLabel.textColor = item.textColor ?: _scoreLevelLabel.textColor;
            _scoreLevelLabel.text = item.levelName;
            break;
        }
    }
    [self startProgressAnimation];
}

- (void)setFrame:(CGRect)frame {
    CGFloat wh = MIN(frame.size.width, frame.size.height);
    frame.size = CGSizeMake(wh, wh);
    [super setFrame:frame];
}

- (void)setBounds:(CGRect)bounds {
    CGFloat wh = MIN(bounds.size.width, bounds.size.height);
    bounds.size = CGSizeMake(wh, wh);
    [super setBounds:bounds];
}

@end
